package com.powerbosframework.web.action;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.powerbosframework.beans.BeanObjectFactory;
import com.powerbosframework.beans.access.BeanFactory;
import com.powerbosframework.beans.access.Getter;
import com.powerbosframework.beans.access.Setter;
import com.powerbosframework.beans.entity.BeanEntity;
import com.powerbosframework.beans.entity.ViewEntity;
import com.powerbosframework.context.ApplicationContext;
import com.powerbosframework.log.LogFactory;
import com.powerbosframework.log.Logger;
import com.powerbosframework.util.TypeConvertUtil;
import com.powerbosframework.web.action.ActionDispatcher;
import com.powerbosframework.web.form.ActionForm;
import com.powerbosframework.web.servlet.ActionServlet;

/**
 * 请求处理器
 * 
 * @author youfu.wang
 * @version 1.0
 */
public class RequestProcessor {

	private static RequestProcessor instance = null;
	public static final String valueStack = "valueStack";
	private ApplicationContext applicationContext;
	private ActionServlet actionServlet;

	private static Logger log = LogFactory.getInstance();

	public RequestProcessor() {
		applicationContext = null;
		actionServlet = null;
	}

	/**
	 * 得到请求处理器实例
	 * 
	 * @return
	 */
	public static RequestProcessor getRequestProcessor() {
		if (instance == null) {
			instance = new RequestProcessor();
		}
		return instance;
	}

	/**
	 * 初始化请求处理器
	 * 
	 * @param actionServlet
	 * @param moduleConfig
	 * @throws ServletException
	 */
	public void init(ApplicationContext applicationContext,
			ActionServlet actionServlet) throws ServletException {
		this.applicationContext = applicationContext;
		this.actionServlet = actionServlet;
	}

	/**
	 * 处理请求
	 * 
	 * @param httpservletrequest
	 * @param httpservletresponse
	 * @throws ActionException
	 * @throws Exception
	 */
	public void process(HttpServletRequest request,HttpServletResponse response)
		throws ActionException,Exception {

		String s = this.processPath(request, response);
		if (s == null)
			return;
		
		SupportAction supportAction = null;				
		supportAction = (SupportAction) this.applicationContext.getBeanObject(s);
		
		ActionDispatcher dispatcher = new ActionDispatcher(request,response);
		ActionContext actionContext = new ActionContext(request,response);
		actionContext.getValueStack().set(GlobalMessage.GLOBAL_KEY,
				GlobalMessage.GLOBAL_VALUE);
		if (supportAction == null) {			
			request.removeAttribute(valueStack);
			request.setAttribute(valueStack, actionContext
					.getValueStack());		
			dispatcher.dispatcher(s,this.applicationContext.getGlobalView(s));
		} else {
			BeanEntity beanEntity=this.applicationContext.getBeanEntity(s);			
			if(beanEntity==null){
				String msg="The requested resource "+s+" is not available";
				dispatcher.doDispatcherError(404, msg);
			}else{			
				//处理表单	
				actionContext.processActionForm(supportAction);
				actionContext.setServletContext(actionServlet.getServletContext());
				supportAction.setApplicationContext(this.applicationContext);
				supportAction.setActionContext(actionContext);					
				//执行动作
				String result=this.processActionExecute(supportAction,beanEntity.getMethod());
				//处理全局堆栈
				processValueStack(request, supportAction);				
				if(result==null||"null".equals(result)) return;			
				dispatcher.dispatcher(s,beanEntity.getViewEntity());
			}		
			return;
		}
	}	
	/**
	 * 处理请求的action执行
	 * 
	 * @param httpservletrequest
	 * @param httpservletresponse
	 * @param supportaction
	 * @param actionconfig
	 * @return
	 * @throws Exception
	 */
	public String processActionExecute(SupportAction supportaction,String methodName) throws Exception {
		String forward = "";
		try {			
			if (methodName == null)
				methodName = "";
			// 默认调用execute方法
			if ("".equals(methodName))
				methodName = "execute";			
			Method method = supportaction.getClass().getMethod(methodName);
			forward = String.valueOf(method.invoke(supportaction));
		} catch (Exception exception) {
			throw exception;
		}
		return forward;
	}

	/**
	 * 处理页面请求的路径,并且返回该请求路径
	 * 
	 * @param httpservletrequest
	 * @param httpservletresponse
	 * @return
	 */
	private String processPath(HttpServletRequest httpservletrequest,
			HttpServletResponse httpservletresponse) {
		String s = null;
		s = (String) httpservletrequest
				.getAttribute("javax.servlet.include.path_info");
		if (s == null)
			s = httpservletrequest.getPathInfo();
		if (s != null && s.length() >= 0) {
			return s;
		}

		s = (String) httpservletrequest
				.getAttribute("javax.servlet.include.servlet_path");
		if (s == null)
			s = httpservletrequest.getServletPath();
		s = ActionDispatcher.redirectURL(s);
		return s;
	}
	/**
	 * 处理action属性对象,存入系统的ValueStack
	 * 
	 * @param supportaction
	 */
	private void processValueStack(HttpServletRequest httpservletrequest,
			SupportAction supportaction) {
//		Field[] fields = supportaction.getClass().getDeclaredFields();
//		for (Field field : fields) {
//			String name = field.getName();
//			Getter getter = BeanFactory.getGetter(supportaction.getClass(), name);
//			Object value = getter.get(supportaction);
//			supportaction.getActionContext().set(name, value);
//		}
		httpservletrequest.removeAttribute(valueStack);
		httpservletrequest.setAttribute(valueStack, supportaction
				.getActionContext().getValueStack());
	}
}
